//! # 分布式配置客户端
//!
//! 提供分布式配置中心的客户端实现，采用面向接口编程设计，
//! 支持远程配置获取、配置缓存、配置监听、配置刷新等功能。
//!
//! ## 设计原则
//!
//! * **面向接口编程** - 所有组件通过trait接口交互
//! * **依赖注入** - 通过构建器模式注入具体实现
//! * **高内聚低耦合** - 模块职责单一，接口清晰
//! * **容错设计** - 支持缓存降级和故障转移
//! * **实时性** - 支持配置变更实时通知

pub mod cache;
pub mod refresh;
pub mod remote;
pub mod watcher;

use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, SystemTime};

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use tokio::sync::{broadcast, RwLock};
use tracing::{info, warn, error};

use crate::core::*;
use crate::RustCloudConfig;
use crate::source::ConfigSource;
use crate::error::{ConfigCenterError, ConfigCenterResult};

/// 变更频率跟踪器
#[derive(Debug, Clone)]
pub struct ChangeFrequencyTracker {
    /// 总检查次数
    total_checks: u64,
    /// 变更次数
    change_count: u64,
    /// 最后检查时间
    last_check: SystemTime,
    /// 最后变更时间
    last_change: Option<SystemTime>,
    /// 近期变更记录（最近25次）
    recent_changes: Vec<SystemTime>,
}

impl ChangeFrequencyTracker {
    /// 创建新的跟踪器
    pub fn new() -> Self {
        Self {
            total_checks: 0,
            change_count: 0,
            last_check: SystemTime::now(),
            last_change: None,
            recent_changes: Vec::new(),
        }
    }
    
    /// 记录一次变更
    pub fn record_change(&mut self) {
        let now = SystemTime::now();
        self.total_checks += 1;
        self.change_count += 1;
        self.last_check = now;
        self.last_change = Some(now);
        
        // 保持最近25次变更记录
        self.recent_changes.push(now);
        if self.recent_changes.len() > 25 {
            self.recent_changes.remove(0);
        }
    }
    
    /// 记录一次无变更检查
    pub fn record_no_change(&mut self) {
        self.total_checks += 1;
        self.last_check = SystemTime::now();
    }
    
    /// 计算自适应间隔
    pub fn calculate_adaptive_interval(&self, base_interval: Duration) -> Duration {
        if self.total_checks < 5 {
            return base_interval;
        }
        
        let change_rate = self.change_count as f64 / self.total_checks as f64;
        
        // 基于变更率调整间隔
        let multiplier = if change_rate > 0.5 {
            // 高变更率，减小间隔
            0.5
        } else if change_rate > 0.2 {
            // 中等变更率，轻微减小间隔
            0.8
        } else if change_rate > 0.05 {
            // 低变更率，保持基础间隔
            1.0
        } else {
            // 极低变更率，增加间隔
            2.0
        };
        
        let new_interval = Duration::from_secs_f64(base_interval.as_secs_f64() * multiplier);
        
        // 限制在合理范围内
        let min_interval = Duration::from_secs(5);
        let max_interval = Duration::from_secs(600);
        
        if new_interval < min_interval {
            min_interval
        } else if new_interval > max_interval {
            max_interval
        } else {
            new_interval
        }
    }
    
    /// 获取变更率
    pub fn get_change_rate(&self) -> f64 {
        if self.total_checks == 0 {
            0.0
        } else {
            self.change_count as f64 / self.total_checks as f64
        }
    }
}

impl Default for ChangeFrequencyTracker {
    fn default() -> Self {
        Self::new()
    }
}

/// 配置客户端错误类型
#[derive(thiserror::Error, Debug)]
pub enum ConfigurationClientError {
    #[error("服务器连接失败: {0}")]
    ServerConnectionError(String),
    
    #[error("配置获取失败: {0}")]
    ConfigurationFetchError(String),
    
    #[error("配置获取失败: {0}")]
    ConfigFetchError(String),
    
    #[error("缓存错误: {0}")]
    CacheError(String),
    
    #[error("监听错误: {0}")]
    WatchError(String),
    
    #[error("HTTP错误: {source}")]
    HttpError {
        #[from]
        source: reqwest::Error,
    },
    
    #[error("序列化错误: {source}")]
    SerializationError {
        #[from]
        source: serde_json::Error,
    },
    
    #[error("核心接口错误: {source}")]
    CoreError {
        #[from]
        source: Box<dyn std::error::Error + Send + Sync>,
    },
}

/// 客户端操作结果类型别名
pub type ConfigClientResult<T> = std::result::Result<T, ConfigurationClientError>;

/// 向后兼容的类型别名
pub type ConfigClientError = ConfigurationClientError;

/// 客户端操作结果类型别名（短名）
pub type ClientResult<T> = std::result::Result<T, ConfigurationClientError>;

/// 配置环境信息（使用核心接口中的定义）
pub type ConfigEnvironment = crate::core::ConfigEnvironment;

/// 配置变更事件
#[derive(Debug, Clone)]
pub struct ConfigChangeEvent {
    /// 事件类型
    pub event_type: ConfigEventType,
    /// 环境信息
    pub environment: ConfigEnvironment,
    /// 新配置
    pub new_config: Option<RustCloudConfig>,
    /// 旧配置
    pub old_config: Option<RustCloudConfig>,
    /// 变更时间
    pub timestamp: SystemTime,
}

/// 配置事件类型
#[derive(Debug, Clone, PartialEq)]
pub enum ConfigEventType {
    /// 配置更新
    Updated,
    /// 配置删除
    Deleted,
    /// 配置创建
    Created,
    /// 服务器连接状态变更
    ConnectionChanged,
}

/// 配置变更监听器trait
#[async_trait]
pub trait ConfigChangeListener: Send + Sync {
    /// 处理配置变更事件
    async fn on_config_change(&self, event: ConfigChangeEvent) -> ClientResult<()>;
}

/// 配置缓存trait（继承核心接口）
#[async_trait]
pub trait ConfigCache: ConfigurationCache + Send + Sync {
    /// 获取缓存的配置（简化接口）
    async fn get_config(&self, environment: &ConfigEnvironment) -> ClientResult<Option<RustCloudConfig>> {
        match self.get(environment).await {
            Ok(Some(data)) => Ok(Some(data.config)),
            Ok(None) => Ok(None),
            Err(e) => Err(ConfigurationClientError::CoreError { source: e }),
        }
    }
    
    /// 保存配置到缓存（简化接口）
    async fn put_config(&self, environment: &ConfigEnvironment, config: &RustCloudConfig) -> ClientResult<()> {
        let data = ConfigurationData {
            environment: environment.clone(),
            config: config.clone(),
            version: "latest".to_string(),
            last_modified: SystemTime::now(),
            source: "client".to_string(),
            properties: HashMap::new(),
        };
        self.put(&data).await
            .map_err(|e| ConfigurationClientError::CoreError { source: e })
    }
}

/// 远程配置获取trait（继承核心接口）
#[async_trait]
pub trait RemoteConfigFetcher: ConfigurationProvider + Send + Sync {
    /// 从远程服务器获取配置（简化接口）
    async fn fetch_config(&self, environment: &ConfigEnvironment) -> ClientResult<RustCloudConfig> {
        self.get_configuration(environment).await
            .map(|data| data.config)
            .map_err(|e| ConfigurationClientError::CoreError { source: e })
    }
    
    /// 检查服务器健康状态
    async fn health_check(&self) -> ClientResult<bool>;
    
    /// 获取配置版本信息
    async fn get_version(&self, environment: &ConfigEnvironment) -> ClientResult<String>;
}

/// 配置客户端配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigClientConfig {
    /// 配置服务器URL列表（支持多服务器）
    pub server_urls: Vec<String>,
    /// 应用名称
    pub application: String,
    /// 环境配置
    pub profile: String,
    /// 版本标签
    pub label: String,
    /// 连接超时时间
    pub connect_timeout: Duration,
    /// 读取超时时间
    pub read_timeout: Duration,
    /// 重试次数
    pub retry_count: u32,
    /// 重试间隔
    pub retry_interval: Duration,
    /// 启用本地缓存
    pub cache_enabled: bool,
    /// 缓存TTL
    pub cache_ttl: Duration,
    /// 启用配置刷新
    pub refresh_enabled: bool,
    /// 刷新间隔
    pub refresh_interval: Duration,
    /// 启用快速失败（服务器不可用时直接使用缓存）
    pub fail_fast: bool,
    /// 用户认证信息
    pub auth_token: Option<String>,
    /// 启用自适应刷新
    pub adaptive_refresh_enabled: bool,
    /// 自适应刷新最小间隔
    pub adaptive_min_interval: Duration,
    /// 自适应刷新最大间隔
    pub adaptive_max_interval: Duration,
}

impl Default for ConfigClientConfig {
    fn default() -> Self {
        Self {
            server_urls: vec!["http://localhost:8888".to_string()],
            application: "application".to_string(),
            profile: "default".to_string(),
            label: "main".to_string(),
            connect_timeout: Duration::from_secs(5),
            read_timeout: Duration::from_secs(10),
            retry_count: 3,
            retry_interval: Duration::from_millis(500),
            cache_enabled: true,
            cache_ttl: Duration::from_secs(300),
            refresh_enabled: true,
            refresh_interval: Duration::from_secs(30),
            fail_fast: false,
            auth_token: None,
            adaptive_refresh_enabled: false,
            adaptive_min_interval: Duration::from_secs(10),
            adaptive_max_interval: Duration::from_secs(300),
        }
    }
}

/// 配置客户端构建器
pub struct ConfigClientBuilder {
    config: ConfigClientConfig,
    cache: Option<Arc<dyn ConfigCache>>,
    fetcher: Option<Arc<dyn RemoteConfigFetcher>>,
    listeners: Vec<Arc<dyn ConfigChangeListener>>,
}

impl ConfigClientBuilder {
    /// 创建新的构建器
    pub fn new() -> Self {
        Self {
            config: ConfigClientConfig::default(),
            cache: None,
            fetcher: None,
            listeners: Vec::new(),
        }
    }
    
    /// 设置服务器URL
    pub fn server_url(mut self, url: &str) -> Self {
        self.config.server_urls = vec![url.to_string()];
        self
    }
    
    /// 设置多个服务器URL
    pub fn server_urls(mut self, urls: Vec<String>) -> Self {
        self.config.server_urls = urls;
        self
    }
    
    /// 设置应用名称
    pub fn application(mut self, application: &str) -> Self {
        self.config.application = application.to_string();
        self
    }
    
    /// 设置环境配置
    pub fn profile(mut self, profile: &str) -> Self {
        self.config.profile = profile.to_string();
        self
    }
    
    /// 设置版本标签
    pub fn label(mut self, label: &str) -> Self {
        self.config.label = label.to_string();
        self
    }
    
    /// 启用本地缓存
    pub fn enable_cache(mut self) -> Self {
        self.config.cache_enabled = true;
        self
    }
    
    /// 禁用本地缓存
    pub fn disable_cache(mut self) -> Self {
        self.config.cache_enabled = false;
        self
    }
    
    /// 启用配置刷新
    pub fn enable_refresh(mut self) -> Self {
        self.config.refresh_enabled = true;
        self
    }
    
    /// 禁用配置刷新
    pub fn disable_refresh(mut self) -> Self {
        self.config.refresh_enabled = false;
        self
    }
    
    /// 设置刷新间隔
    pub fn refresh_interval(mut self, interval: Duration) -> Self {
        self.config.refresh_interval = interval;
        self
    }
    
    /// 设置认证token
    pub fn auth_token(mut self, token: &str) -> Self {
        self.config.auth_token = Some(token.to_string());
        self
    }
    
    /// 设置自定义缓存实现
    pub fn with_cache(mut self, cache: Arc<dyn ConfigCache>) -> Self {
        self.cache = Some(cache);
        self
    }
    
    /// 设置自定义远程获取器
    pub fn with_fetcher(mut self, fetcher: Arc<dyn RemoteConfigFetcher>) -> Self {
        self.fetcher = Some(fetcher);
        self
    }
    
    /// 添加配置变更监听器
    pub fn add_listener(mut self, listener: Arc<dyn ConfigChangeListener>) -> Self {
        self.listeners.push(listener);
        self
    }
    
    /// 构建配置客户端
    pub async fn build(self) -> ClientResult<ConfigClient> {
        ConfigClient::new(
            self.config,
            self.cache,
            self.fetcher,
            self.listeners,
        ).await
    }
}

/// 配置客户端主结构
pub struct ConfigClient {
    /// 客户端配置
    config: ConfigClientConfig,
    /// 配置缓存
    cache: Option<Arc<dyn ConfigCache>>,
    /// 远程配置获取器
    fetcher: Arc<dyn RemoteConfigFetcher>,
    /// 配置变更监听器列表
    listeners: Vec<Arc<dyn ConfigChangeListener>>,
    /// 当前配置
    current_config: Arc<RwLock<Option<RustCloudConfig>>>,
    /// 配置变更通知器
    change_notifier: broadcast::Sender<ConfigChangeEvent>,
    /// 配置变更接收器
    _change_receiver: broadcast::Receiver<ConfigChangeEvent>,
}

impl ConfigClient {
    /// 创建新的配置客户端
    pub async fn new(
        config: ConfigClientConfig,
        cache: Option<Arc<dyn ConfigCache>>,
        fetcher: Option<Arc<dyn RemoteConfigFetcher>>,
        listeners: Vec<Arc<dyn ConfigChangeListener>>,
    ) -> ClientResult<Self> {
        // 创建默认的远程获取器
        let fetcher = match fetcher {
            Some(f) => f,
            None => Arc::new(remote::HttpConfigFetcher::new(&config)?),
        };
        
        // 创建默认的缓存
        let cache = if config.cache_enabled {
            match cache {
                Some(c) => Some(c),
                None => Some(Arc::new(cache::MemoryConfigCache::new(config.cache_ttl)) as Arc<dyn ConfigCache>),
            }
        } else {
            None
        };
        
        // 创建配置变更通知器
        let (change_notifier, change_receiver) = broadcast::channel(64);
        
        let client = Self {
            config,
            cache,
            fetcher,
            listeners,
            current_config: Arc::new(RwLock::new(None)),
            change_notifier,
            _change_receiver: change_receiver,
        };
        
        Ok(client)
    }
    
    /// 创建构建器
    pub fn builder() -> ConfigClientBuilder {
        ConfigClientBuilder::new()
    }
    
    /// 获取配置
    pub async fn get_config(&self) -> ClientResult<RustCloudConfig> {
        let environment = ConfigEnvironment::new(
            &self.config.application,
            &self.config.profile,
            &self.config.label,
        );
        
        // 尝试从缓存获取
        if let Some(cache) = &self.cache {
            if let Ok(Some(cached_config)) = cache.get_config(&environment).await {
                if let Ok(false) = cache.is_expired(&environment).await {
                    tracing::debug!("🎯 从缓存获取配置: {}", environment.application);
                    return Ok(cached_config);
                }
            }
        }
        
        // 从远程服务器获取配置
        match self.fetcher.fetch_config(&environment).await {
            Ok(config) => {
                // 保存到缓存
                if let Some(cache) = &self.cache {
                    if let Err(e) = cache.put_config(&environment, &config).await {
                        tracing::warn!("💾 保存配置到缓存失败: {}", e);
                    }
                }
                
                // 更新当前配置
                let old_config = {
                    let mut current = self.current_config.write().await;
                    let old = current.clone();
                    *current = Some(config.clone());
                    old
                };
                
                // 发送变更通知
                let event = ConfigChangeEvent {
                    event_type: if old_config.is_some() { 
                        ConfigEventType::Updated 
                    } else { 
                        ConfigEventType::Created 
                    },
                    environment: environment.clone(),
                    new_config: Some(config.clone()),
                    old_config,
                    timestamp: SystemTime::now(),
                };
                
                self.notify_change(event).await;
                
                tracing::info!("📖 从远程获取配置: {}", environment.application);
                Ok(config)
            }
            Err(e) => {
                if self.config.fail_fast {
                    return Err(e);
                }
                
                // 尝试使用缓存的配置
                if let Some(cache) = &self.cache {
                    if let Ok(Some(cached_config)) = cache.get_config(&environment).await {
                        tracing::warn!("⚠️ 远程获取配置失败，使用缓存配置: {}", e);
                        return Ok(cached_config);
                    }
                }
                
                Err(e)
            }
        }
    }
    
    /// 刷新配置
    pub async fn refresh_config(&self) -> ClientResult<()> {
        let environment = ConfigEnvironment::new(
            &self.config.application,
            &self.config.profile,
            &self.config.label,
        );
        
        // 获取当前版本
        let current_version = match self.fetcher.get_version(&environment).await {
            Ok(version) => version,
            Err(e) => {
                tracing::warn!("🔄 获取配置版本失败: {}", e);
                return Err(e);
            }
        };
        
        // 检查是否有新版本
        let current_config = self.current_config.read().await;
        if let Some(config) = current_config.as_ref() {
            // 这里需要实现版本比较逻辑
            // 暂时总是刷新
        }
        drop(current_config);
        
        // 重新获取配置
        self.get_config().await?;
        
        tracing::debug!("🔄 配置已刷新: {}", environment.application);
        Ok(())
    }
    
    /// 开始监听配置变更
    pub async fn start_watching(&self) -> ClientResult<()> {
        if !self.config.refresh_enabled {
            return Ok(());
        }
        
        let client = self.clone_for_watching();
        let interval = self.config.refresh_interval;
        
        tokio::spawn(async move {
            let mut ticker = tokio::time::interval(interval);
            loop {
                ticker.tick().await;
                if let Err(e) = client.refresh_config().await {
                    tracing::error!("🔄 配置刷新失败: {}", e);
                }
            }
        });
        
        tracing::info!("👁️ 开始监听配置变更，间隔: {:?}", interval);
        Ok(())
    }
    
    /// 停止监听配置变更
    pub async fn stop_watching(&self) -> ClientResult<()> {
        // 实际实现中需要管理监听任务的生命周期
        tracing::info!("🛑 停止监听配置变更");
        Ok(())
    }
    
    /// 订阅配置变更事件
    pub fn subscribe_changes(&self) -> broadcast::Receiver<ConfigChangeEvent> {
        self.change_notifier.subscribe()
    }
    
    /// 获取当前配置
    pub async fn get_current_config(&self) -> Option<RustCloudConfig> {
        self.current_config.read().await.clone()
    }
    
    /// 清除本地缓存
    pub async fn clear_cache(&self) -> ClientResult<()> {
        if let Some(cache) = &self.cache {
            cache.clear().await?;
            tracing::info!("🧹 本地缓存已清除");
        }
        Ok(())
    }
    
    /// 检查服务器健康状态
    pub async fn health_check(&self) -> ClientResult<bool> {
        self.fetcher.health_check().await
    }
    
    /// 启用自适应刷新机制
    /// 
    /// 基于配置变更频率动态调整刷新间隔
    pub async fn enable_adaptive_refresh(&self) -> ClientResult<()> {
        if !self.config.adaptive_refresh_enabled {
            info!("⚠️ 自适应刷新未启用");
            return Ok(());
        }
        
        info!("🔄 启动自适应刷新机制");
        
        let environment = ConfigEnvironment::new(
            &self.config.application,
            &self.config.profile,
            &self.config.label,
        );
        
        let fetcher = self.fetcher.clone();
        let config_cache = self.cache.clone();
        let adaptive_config = self.config.clone();
        let change_frequency = Arc::new(RwLock::new(ChangeFrequencyTracker::new()));
        let event_notifier = self.change_notifier.clone();
        
        let change_frequency_clone = change_frequency.clone();
        tokio::spawn(async move {
            let base_interval = adaptive_config.refresh_interval;
            info!("📊 自适应刷新已启动，基础间隔: {:?}", base_interval);
            
            loop {
                let env_key = format!("{}:{}:{}", 
                    environment.application, environment.profile, environment.label);
                
                // 获取当前变更频率
                let current_interval = {
                    let frequency = change_frequency_clone.read().await;
                    frequency.calculate_adaptive_interval(base_interval)
                };
                
                debug!("📈 环境 {} 自适应间隔: {:?}", env_key, current_interval);
                
                // 检查配置是否需要更新
                if let Err(e) = Self::adaptive_config_check(
                    &environment,
                    &fetcher,
                    &config_cache,
                    &change_frequency_clone,
                    &event_notifier,
                ).await {
                    warn!("⚠️ 自适应配置检查失败 {}: {}", env_key, e);
                }
                
                // 使用自适应间隔
                tokio::time::sleep(current_interval).await;
            }
        });
        
        info!("✅ 自适应刷新机制已启动");
        Ok(())
    }
    
    /// 自适应配置检查
    async fn adaptive_config_check(
        environment: &ConfigEnvironment,
        fetcher: &Arc<dyn RemoteConfigFetcher>,
        config_cache: &Option<Arc<dyn ConfigCache>>,
        change_frequency: &Arc<RwLock<ChangeFrequencyTracker>>,
        event_notifier: &broadcast::Sender<ConfigChangeEvent>,
    ) -> ClientResult<()> {
        let env_key = format!("{}:{}:{}", 
            environment.application, environment.profile, environment.label);
        
        // 获取当前版本
        let current_version = fetcher.get_version(environment).await?;
        
        // 检查缓存中的版本
        let (cached_config, cache_version) = if let Some(cache) = config_cache {
            let cached = cache.get_config(environment).await?;
            let version = cached.as_ref().map(|_| "cached".to_string());
            (cached, version)
        } else {
            (None, None)
        };
        
        let has_changed = match cache_version {
            Some(cached_ver) => cached_ver != current_version,
            None => true,
        };
        
        // 更新变更频率跟踪
        {
            let mut frequency = change_frequency.write().await;
            
            if has_changed {
                frequency.record_change();
                info!("📝 检测到配置变更: {} -> {}", 
                    cache_version.unwrap_or("none".to_string()), current_version);
                
                // 获取新配置并更新缓存
                let new_config = fetcher.fetch_config(environment).await?;
                if let Some(cache) = config_cache {
                    cache.put_config(environment, &new_config).await?;
                }
                
                // 发送变更事件
                let event = ConfigChangeEvent {
                    event_type: if cached_config.is_some() { 
                        ConfigEventType::Updated 
                    } else { 
                        ConfigEventType::Created 
                    },
                    environment: environment.clone(),
                    new_config: Some(new_config),
                    old_config: cached_config,
                    timestamp: SystemTime::now(),
                };
                
                if let Err(e) = event_notifier.send(event) {
                    warn!("⚠️ 发送自适应刷新事件失败: {}", e);
                }
            } else {
                frequency.record_no_change();
                debug!("🔄 配置无变更: {}", env_key);
            }
        }
        
        Ok(())
    }
    
    /// 获取客户端配置
    pub fn get_client_config(&self) -> &ConfigClientConfig {
        &self.config
    }
    
    /// 通知配置变更
    async fn notify_change(&self, event: ConfigChangeEvent) {
        // 发送广播通知
        if let Err(e) = self.change_notifier.send(event.clone()) {
            tracing::warn!("📢 发送配置变更通知失败: {}", e);
        }
        
        // 通知所有监听器
        for listener in &self.listeners {
            if let Err(e) = listener.on_config_change(event.clone()).await {
                tracing::warn!("👂 配置变更监听器处理失败: {}", e);
            }
        }
    }
    
    /// 克隆用于监听的客户端实例
    fn clone_for_watching(&self) -> Self {
        Self {
            config: self.config.clone(),
            cache: self.cache.clone(),
            fetcher: self.fetcher.clone(),
            listeners: self.listeners.clone(),
            current_config: self.current_config.clone(),
            change_notifier: self.change_notifier.clone(),
            _change_receiver: self.change_notifier.subscribe(),
        }
    }
}

impl Clone for ConfigClient {
    fn clone(&self) -> Self {
        self.clone_for_watching()
    }
}

/// 实现 ConfigSource trait 支持
/// 暂时注释，等待正确的引用修复
/*
#[async_trait]
impl ConfigSource for ConfigClient {
    async fn load_config(&mut self) -> crate::Result<RustCloudConfig> {
        self.get_config().await
            .map_err(|e| crate::ConfigError::LoadError(e.to_string()))
    }
    
    fn get_source_name(&self) -> String {
        format!("ConfigServer[{}]", self.config.server_urls.join(","))
    }
}
*/

impl Default for ConfigClientBuilder {
    fn default() -> Self {
        Self::new()
    }
}